package org.smallreunion.controller.authntication;

import org.slim3.controller.Navigation;
import org.slim3.util.AppEngineUtil;
import org.smallreunion.controller.AbstractController;
import org.smallreunion.model.Member;
import org.smallreunion.service.MemberService;
import org.smallreunion.service.SessionService;
import org.smallreunion.twitter.Twitter4sr;
import org.smallreunion.twitter.Twitter4srFactory;
import org.smallreunion.util.StringUtil;
import org.smallreunion.var.LoginInfo;

import twitter4j.auth.AccessToken;
import twitter4j.auth.RequestToken;

/**
 * AuthnticationCallbackController
 *
 * @author Sinmetal
 *
 */
public class CallbackController extends AbstractController {

    private MemberService memberService = new MemberService();

    private SessionService sessionService = new SessionService();

    /**
     * User情報をDatastoreに保存
     */
    @Override
    public Navigation run() throws Exception {
        final String BBS_PAGE = "/bbs";
        if (!AppEngineUtil.isServer() || AppEngineUtil.isDevelopment()) {
            Member testMember = createTestMember();
            saveMember(testMember);
            return redirect(BBS_PAGE);
        }

        Twitter4sr twitter = new Twitter4srFactory().getInstance();

        RequestToken requestToken = getRequestToken();
        String verifier = requestScope("oauth_verifier");
        if (StringUtil.isEmpty(verifier)) {
            // 認証取消
            return redirect("/");
        }
        AccessToken accessToken =
            twitter.getOAuthAccessToken(requestToken, verifier);

        Member member = Member.getInstance(twitter.getUser(), accessToken);
        saveMember(member);
        return redirect(BBS_PAGE);
    }

    /**
     * メンバー保存
     *
     * @param member
     * @return
     */
    private Member saveMember(Member member) {
        if (member == null) {
            return null;
        }
        Member store = memberService.insert(member);
        LoginInfo loginInfo = LoginInfo.getInstance(store);
        entryAuthToken(loginInfo, true);
        return store;
    }

    /**
     * RequestTokenを取得
     *
     * @return
     */
    private RequestToken getRequestToken() {
        String token = getSessionToken();
        RequestToken requestToken = sessionService.getRequestToken(token);
        sessionService.deleteRequestToken(token);
        return requestToken;
    }

    /**
     * Local実行時のテスト用に擬似メンバー情報を作成
     *
     * @return
     */
    private Member createTestMember() {
        Member member = new Member();
        member.setTwitterId(1L);
        member.setTwitterName("真");
        member.setTwitterScreenName("sinmetal");
        member
            .setTwitterProfileImageUrl("http://a2.twimg.com/profile_images/1042264867/1277990403846_bigger.png");
        return member;
    }
}
